{% extends "layout.html" %}

{% block title %}AI智能助手 - ChatGPT{% endblock %}

{% block css %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/ai_assistant.css') }}">
<!-- 添加Markdown解析库 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/marked/lib/marked.min.css">
<style>
    /* 整体布局优化 */
    .ai-container {
        display: flex;
        flex-direction: column;
        height: calc(100vh - 120px);
        max-width: 1200px;
        margin: 0 auto;
        background-color: #f9f9f9;
        border-radius: 12px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
        overflow: hidden;
    }
    
    .chat-container {
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }
    
    .chat-header {
        padding: 15px 20px;
        background-color: #ffffff;
        border-bottom: 1px solid #e0e0e0;
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    
    .chat-title {
        font-size: 18px;
        font-weight: 600;
        color: #333;
        display: flex;
        align-items: center;
    }
    
    .chat-title i {
        margin-right: 8px;
        color: var(--primary-color);
    }
    
    .chat-area {
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;
        position: relative;
    }

    /* 功能控制区样式优化 */
    .feature-controls {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
        padding: 12px 20px;
        background-color: #f1f1f1;
        border-bottom: 1px solid #e0e0e0;
    }
    
    .feature-toggle {
        display: flex;
        align-items: center;
        background-color: #fff;
        padding: 6px 12px;
        border-radius: 20px;
        box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }
    
    .feature-toggle label {
        margin-left: 5px;
        font-size: 14px;
        cursor: pointer;
        user-select: none;
    }
    
    /* 自定义开关样式 */
    .toggle-switch {
        position: relative;
        display: inline-block;
        width: 36px;
        height: 20px;
    }
    
    .toggle-switch input {
        opacity: 0;
        width: 0;
        height: 0;
    }
    
    .toggle-slider {
        position: absolute;
        cursor: pointer;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: #ccc;
        transition: .4s;
        border-radius: 20px;
    }
    
    .toggle-slider:before {
        position: absolute;
        content: "";
        height: 16px;
        width: 16px;
        left: 2px;
        bottom: 2px;
        background-color: white;
        transition: .4s;
        border-radius: 50%;
    }
    
    input:checked + .toggle-slider {
        background-color: var(--primary-color);
    }
    
    input:checked + .toggle-slider:before {
        transform: translateX(16px);
    }
    
    .clear-history {
        background-color: #ff4d4f;
        color: white;
        border: none;
        padding: 6px 12px;
        border-radius: 20px;
        cursor: pointer;
        font-size: 14px;
        transition: background-color 0.3s;
        display: flex;
        align-items: center;
    }
    
    .clear-history i {
        font-size: 12px;
        margin-right: 4px;
    }
    
    .clear-history:hover {
        background-color: #ff7875;
    }
    
    .context-info {
        font-size: 12px;
        color: #666;
        margin-left: auto;
        display: flex;
        align-items: center;
        padding: 6px 12px;
        background-color: #fff;
        border-radius: 20px;
    }
    
    /* 消息区域优化 */
    .messages {
        flex: 1;
        overflow-y: auto;
        padding: 20px;
        background-color: #f9f9f9;
    }
    
    .message {
        margin-bottom: 20px;
        max-width: 85%;
        animation: fadeIn 0.3s ease;
    }
    
    @keyframes fadeIn {
        from { opacity: 0; transform: translateY(10px); }
        to { opacity: 1; transform: translateY(0); }
    }
    
    .user-message {
        margin-left: auto;
        background-color: #e3f2fd;
        border-radius: 18px 18px 4px 18px;
    }
    
    .ai-message {
        margin-right: auto;
        background-color: #ffffff;
        border-radius: 18px 18px 18px 4px;
        box-shadow: 0 1px 2px rgba(0,0,0,0.1);
    }
    
    .message-sender {
        font-weight: 600;
        font-size: 14px;
        padding: 10px 15px 5px;
        display: block;
        color: #444;
    }
    
    .message-content {
        padding: 0 15px 10px;
        word-break: break-word;
        line-height: 1.5;
    }
    
    .message-time {
        display: block;
        font-size: 10px;
        color: #888;
        text-align: right;
        padding: 0 15px 5px;
    }
    
    /* 添加消息来源标签 */
    .message-model {
        font-size: 12px;
        color: #888;
        margin-left: 8px;
        font-weight: normal;
    }
    
    /* 网络搜索标签 */
    .web-search-tag {
        display: inline-block;
        font-size: 11px;
        background-color: #4caf50;
        color: white;
        padding: 2px 6px;
        border-radius: 10px;
        margin-left: 6px;
        vertical-align: middle;
    }
    
    /* 输入区域优化 */
    .input-area {
        background-color: #fff;
        padding: 15px;
        border-top: 1px solid #e0e0e0;
    }
    
    .input-actions {
        display: flex;
        margin-bottom: 10px;
    }
    
    .upload-image {
        display: flex;
        align-items: center;
        background-color: #f1f1f1;
        border: none;
        padding: 8px 12px;
        border-radius: 20px;
        cursor: pointer;
        font-size: 14px;
        transition: background-color 0.3s;
    }
    
    .upload-image svg {
        width: 18px;
        height: 18px;
        margin-right: 5px;
    }
    
    .upload-image:hover {
        background-color: #e0e0e0;
    }
    
    .file-input {
        display: none;
    }
    
    .preview-container {
        display: none;
        margin-bottom: 10px;
        position: relative;
        max-width: 200px;
    }
    
    .preview-image {
        width: 100%;
        border-radius: 8px;
        box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    }
    
    .remove-image {
        position: absolute;
        top: -8px;
        right: -8px;
        width: 22px;
        height: 22px;
        border-radius: 50%;
        background-color: #f44336;
        color: white;
        border: none;
        font-size: 14px;
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    
    .input-container {
        display: flex;
        background-color: #f1f1f1;
        border-radius: 24px;
        padding: 4px;
    }
    
    .message-input {
        flex: 1;
        border: none;
        outline: none;
        padding: 12px 16px;
        border-radius: 20px;
        resize: none;
        max-height: 120px;
        background-color: #f1f1f1;
        font-family: inherit;
        font-size: 15px;
    }
    
    .send-button {
        background-color: var(--primary-color);
        color: white;
        border: none;
        width: 40px;
        height: 40px;
        border-radius: 50%;
        cursor: pointer;
        transition: background-color 0.3s;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    
    .send-button:hover {
        background-color: var(--primary-color-dark);
    }
    
    /* 正在输入指示器样式 */
    .typing-indicator {
        display: flex;
        align-items: center;
        gap: 5px;
    }
    
    .typing-dot {
        width: 8px;
        height: 8px;
        background-color: #aaa;
        border-radius: 50%;
        animation: typingAnimation 1.5s infinite ease-in-out;
    }
    
    .typing-dot:nth-child(2) {
        animation-delay: 0.2s;
    }
    
    .typing-dot:nth-child(3) {
        animation-delay: 0.4s;
    }
    
    @keyframes typingAnimation {
        0%, 60%, 100% { transform: translateY(0); }
        30% { transform: translateY(-5px); }
    }
    
    /* 响应式设计 */
    @media (max-width: 768px) {
        .ai-container {
            height: calc(100vh - 100px);
            border-radius: 0;
        }
        
        .message {
            max-width: 90%;
        }
        
        .feature-controls {
            padding: 8px 12px;
            gap: 6px;
        }
        
        .feature-toggle {
            padding: 4px 8px;
            font-size: 12px;
        }
    }
    
    /* 图片查看器样式 */
    .image-viewer {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.9);
        z-index: 1000;
        justify-content: center;
        align-items: center;
        flex-direction: column;
    }
    
    .image-viewer-content {
        max-width: 90%;
        max-height: 90%;
        position: relative;
    }
    
    .image-viewer-img {
        max-width: 100%;
        max-height: 90vh;
        object-fit: contain;
        border-radius: 4px;
    }
    
    .image-viewer-close {
        position: absolute;
        top: 20px;
        right: 30px;
        color: white;
        font-size: 30px;
        cursor: pointer;
        z-index: 1001;
    }
    
    .user-uploaded-image {
        max-width: 200px;
        max-height: 200px;
        border-radius: 8px;
        margin-top: 8px;
        cursor: pointer;
        transition: transform 0.2s;
    }
    
    .user-uploaded-image:hover {
        transform: scale(1.05);
    }
</style>
{% endblock %}

{% block page_title %}AI智能助手{% endblock %}

{% block content %}
<div class="ai-container">
    <div class="chat-container">
        <div class="chat-header">
            <div class="chat-title">
                <i class="fas fa-robot"></i>
                AI智能助手
            </div>
        </div>
        
        <div class="chat-area">
            <div class="feature-controls">
                <div class="feature-toggle">
                    <label class="toggle-switch">
                        <input type="checkbox" id="memory-toggle">
                        <span class="toggle-slider"></span>
                    </label>
                    <label for="memory-toggle">记忆功能</label>
                </div>
                
                <div class="feature-toggle">
                    <label class="toggle-switch">
                        <input type="checkbox" id="web-search-toggle">
                        <span class="toggle-slider"></span>
                    </label>
                    <label for="web-search-toggle">联网搜索</label>
                </div>
                
                <button id="clear-history" class="clear-history">
                    <i class="fas fa-trash-alt"></i>
                    清空历史
                </button>
                
                <div class="context-info">
                    <i class="fas fa-info-circle" style="margin-right: 5px;"></i>
                    上下文: <span id="context-length">1</span> 条消息
                </div>
            </div>
            
            <div class="messages" id="messages">
                <div class="message ai-message">
                    <span class="message-sender">AI助手<span class="message-model">OpenAI兼容模型</span></span>
                    <div class="message-content">
                        您好！我是AI助手，基于OpenAI兼容模型。我可以帮助您回答问题、提供信息，也可以分析图片内容。请输入您的问题或上传图片开始对话吧！
                    </div>
                    <span class="message-time">{{ current_time }}</span>
                </div>
            </div>
            
            <div class="input-area">
                <div class="input-actions">
                    <button class="upload-image" id="upload-trigger">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                            <path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4.86 8.86l-3 3.87L9 13.14 6 17h12l-3.86-5.14z"/>
                        </svg>
                        上传图片
                    </button>
                    <input type="file" id="file-input" class="file-input" accept="image/*">
                </div>
                
                <div class="preview-container" id="preview-container">
                    <img id="preview-image" class="preview-image">
                    <button id="remove-image" class="remove-image">×</button>
                </div>
                
                <div class="input-container">
                    <textarea id="message-input" class="message-input" placeholder="输入您的问题..."></textarea>
                    <button id="send-button" class="send-button">
                        <i class="fas fa-paper-plane"></i>
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 图片查看器 -->
<div class="image-viewer" id="image-viewer">
    <span class="image-viewer-close" id="image-viewer-close">&times;</span>
    <div class="image-viewer-content">
        <img id="image-viewer-img" class="image-viewer-img" src="" alt="查看图片">
    </div>
</div>
{% endblock %}

{% block scripts %}
<!-- 添加Markdown解析库 -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script>
    document.addEventListener('DOMContentLoaded', function() {
        const messagesContainer = document.getElementById('messages');
        const messageInput = document.getElementById('message-input');
        const sendButton = document.getElementById('send-button');
        const fileInput = document.getElementById('file-input');
        const uploadTrigger = document.getElementById('upload-trigger');
        const previewContainer = document.getElementById('preview-container');
        const previewImage = document.getElementById('preview-image');
        const removeImageButton = document.getElementById('remove-image');
        const memoryToggle = document.getElementById('memory-toggle');
        const webSearchToggle = document.getElementById('web-search-toggle');
        const clearHistoryButton = document.getElementById('clear-history');
        const contextLengthDisplay = document.getElementById('context-length');
        
        // 图片查看器元素
        const imageViewer = document.getElementById('image-viewer');
        const imageViewerImg = document.getElementById('image-viewer-img');
        const imageViewerClose = document.getElementById('image-viewer-close');
        
        let uploadedImage = null;
        let isWaitingForResponse = false;
        let messageCount = 1; // 当前上下文中的消息数量
        
        // 配置Markdown解析选项
        marked.setOptions({
            breaks: true, // 允许换行
            gfm: true,    // GitHub风格Markdown
            headerIds: false, // 不生成header IDs
            sanitize: false   // 不进行HTML过滤
        });
        
        // 图片查看器关闭事件
        imageViewerClose.addEventListener('click', function() {
            imageViewer.style.display = 'none';
            document.body.style.overflow = 'auto'; // 恢复滚动
        });
        
        // 点击图片查看器背景也关闭
        imageViewer.addEventListener('click', function(e) {
            if (e.target === imageViewer) {
                imageViewer.style.display = 'none';
                document.body.style.overflow = 'auto';
            }
        });
        
        // 为聊天区域添加事件委托，处理图片点击
        messagesContainer.addEventListener('click', function(e) {
            // 检查点击的是否是用户上传图片或AI显示的图片
            if (e.target.classList.contains('user-uploaded-image') || 
                (e.target.tagName === 'IMG' && e.target.closest('.markdown-content'))) {
                imageViewerImg.src = e.target.src;
                imageViewer.style.display = 'flex';
                document.body.style.overflow = 'hidden'; // 防止滚动
            }
        });
        
        // 清空历史按钮事件
        clearHistoryButton.addEventListener('click', function() {
            if (confirm('确定要清空所有对话历史吗？这将删除所有消息记录。')) {
                // 只保留初始消息
                messagesContainer.innerHTML = `
                    <div class="message ai-message">
                        <span class="message-sender">AI助手<span class="message-model">OpenAI兼容模型</span></span>
                        <div class="message-content">
                            您好！我是AI助手，基于OpenAI兼容模型。我可以帮助您回答问题、提供信息，也可以分析图片内容。请输入您的问题或上传图片开始对话吧！
                        </div>
                        <span class="message-time">${new Date().toLocaleTimeString()}</span>
                    </div>
                `;
                
                // 发送AJAX请求到后端清除历史记录
                fetch('/ai_assistant/clear_history', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    }
                })
                .then(response => response.json())
                .then(data => {
                    console.log("历史记录已清空");
                    // 重置上下文计数
                    messageCount = 1;
                    updateContextLength();
                })
                .catch(error => {
                    console.error('清空历史记录失败:', error);
                });
            }
        });
        
        // 更新上下文长度显示
        function updateContextLength() {
            contextLengthDisplay.textContent = messageCount;
        }
        
        // 自动调整文本框高度
        messageInput.addEventListener('input', function() {
            this.style.height = 'auto';
            this.style.height = (this.scrollHeight) + 'px';
        });
        
        // 上传图片按钮事件
        uploadTrigger.addEventListener('click', function() {
            fileInput.click();
        });
        
        // 文件选择事件
        fileInput.addEventListener('change', function(e) {
            const file = e.target.files[0];
            if (file && file.type.startsWith('image/')) {
                const reader = new FileReader();
                reader.onload = function(event) {
                    previewImage.src = event.target.result;
                    previewContainer.style.display = 'block';
                    uploadedImage = {
                        data: event.target.result,
                        name: file.name
                    };
                };
                reader.readAsDataURL(file);
            }
        });
        
        // 移除图片按钮
        removeImageButton.addEventListener('click', function() {
            previewContainer.style.display = 'none';
            previewImage.src = '';
            fileInput.value = '';
            uploadedImage = null;
        });
        
        // 发送按钮事件
        sendButton.addEventListener('click', sendMessage);
        
        // 回车键发送消息（Shift+Enter换行）
        messageInput.addEventListener('keypress', function(e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendMessage();
            }
        });
        
        function sendMessage() {
            const messageText = messageInput.value.trim();
            
            // 验证是否有内容
            if (!messageText && !uploadedImage) {
                return;
            }
            
            if (isWaitingForResponse) {
                return;
            }
            
            // 添加用户消息到界面
            const currentTime = new Date().toLocaleTimeString();
            let messageHTML = `
                <div class="message user-message">
                    <span class="message-sender">我</span>
                    <div class="message-content">
                        ${messageText.replace(/\n/g, '<br>')}
                    </div>`;
            
            if (uploadedImage) {
                messageHTML += `<div class="message-content">
                    <img src="${uploadedImage.data}" alt="用户上传图片" class="user-uploaded-image">
                </div>`;
            }
            
            messageHTML += `<span class="message-time">${currentTime}</span></div>`;
            messagesContainer.innerHTML += messageHTML;
            
            // 增加消息计数
            messageCount += 1;
            updateContextLength();
            
            // 清空输入
            messageInput.value = '';
            messageInput.style.height = 'auto';
            if (uploadedImage) {
                previewContainer.style.display = 'none';
            }
            
            // 滚动到底部
            messagesContainer.scrollTop = messagesContainer.scrollHeight;
            
            // 显示AI正在输入
            const loadingId = showTypingIndicator();
            isWaitingForResponse = true;
            
            // 获取联网搜索开关状态
            const useWebSearch = webSearchToggle.checked;
            
            // 发送请求到后端
            const requestData = {
                message: messageText,
                with_memory: memoryToggle.checked,
                use_web_search: useWebSearch
            };
            
            if (uploadedImage) {
                requestData.image = uploadedImage.data;
            }
            
            fetch('/ai_assistant/chat', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(requestData)
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error('网络请求失败');
                }
                return response.json();
            })
            .then(data => {
                // 隐藏加载指示器
                hideTypingIndicator(loadingId);
                isWaitingForResponse = false;
                
                // 增加消息计数
                messageCount += 1;
                updateContextLength();
                
                // 使用Markdown解析AI回复
                const parsedResponse = marked.parse(data.response);
                
                // 检查是否使用了联网搜索 (通过响应内容中的标记)
                const usedWebSearch = data.response.includes('*(该回答使用了联网搜索功能提供的信息)*');
                
                // 添加AI回复
                const aiMessageTime = new Date().toLocaleTimeString();
                const aiMessageHTML = `
                    <div class="message ai-message">
                        <span class="message-sender">
                            AI助手
                            <span class="message-model">OpenAI兼容模型</span>
                            ${usedWebSearch ? '<span class="web-search-tag">联网</span>' : ''}
                        </span>
                        <div class="message-content markdown-content">
                            ${parsedResponse}
                        </div>
                        <span class="message-time">${aiMessageTime}</span>
                    </div>
                `;
                messagesContainer.innerHTML += aiMessageHTML;
                
                // 处理代码高亮
                const codeBlocks = document.querySelectorAll('pre code');
                if (codeBlocks.length > 0 && window.hljs) {
                    codeBlocks.forEach(block => {
                        hljs.highlightBlock(block);
                    });
                }
                
                // 处理生成内容中的图片，使其可点击查看
                const aiImages = document.querySelectorAll('.markdown-content img');
                aiImages.forEach(img => {
                    img.style.cursor = 'pointer';
                    img.style.maxWidth = '200px';
                    img.style.maxHeight = '200px';
                    img.style.borderRadius = '8px';
                    img.style.margin = '8px 0';
                });
                
                // 滚动到底部
                messagesContainer.scrollTop = messagesContainer.scrollHeight;
                
                // 重置上传图片
                uploadedImage = null;
            })
            .catch(error => {
                console.error('Error:', error);
                hideTypingIndicator(loadingId);
                isWaitingForResponse = false;
                
                // 显示错误消息
                const errorTime = new Date().toLocaleTimeString();
                const errorHTML = `
                    <div class="message ai-message">
                        <span class="message-sender">系统</span>
                        <div class="message-content" style="color: #d93025;">
                            抱歉，请求处理失败。请稍后再试。
                        </div>
                        <span class="message-time">${errorTime}</span>
                    </div>
                `;
                messagesContainer.innerHTML += errorHTML;
                messagesContainer.scrollTop = messagesContainer.scrollHeight;
            });
        }
        
        // 显示"正在输入"指示器
        function showTypingIndicator() {
            const typingId = 'typing-' + new Date().getTime();
            const typingHTML = `
                <div class="message ai-message" id="${typingId}">
                    <span class="message-sender">AI助手<span class="message-model">OpenAI兼容模型</span></span>
                    <div class="message-content loading-indicator">
                        <div class="typing-indicator">
                            <div class="typing-dot"></div>
                            <div class="typing-dot"></div>
                            <div class="typing-dot"></div>
                        </div>
                    </div>
                </div>
            `;
            messagesContainer.innerHTML += typingHTML;
            messagesContainer.scrollTop = messagesContainer.scrollHeight;
            return typingId;
        }
        
        // 隐藏"正在输入"指示器
        function hideTypingIndicator(typingId) {
            const typingElement = document.getElementById(typingId);
            if (typingElement) {
                typingElement.remove();
            }
        }
    });
</script>
{% endblock %} 